package languageacquisition;

import jade.content.ContentElement;
import jade.content.abs.AbsConcept;
import jade.content.abs.AbsIRE;
import jade.content.abs.AbsPredicate;
import jade.content.abs.AbsVariable;
import jade.content.lang.Codec.CodecException;
import jade.content.lang.sl.SLVocabulary;
import jade.content.onto.Ontology;
import jade.content.onto.OntologyException;
import jade.content.onto.UngroundedException;
import jade.core.AID;
import jade.core.Agent;
import jade.domain.FIPANames;
import jade.lang.acl.ACLMessage;
import jade.proto.AchieveREInitiator;

import java.util.Vector;

import languageacquisition.ontology.EnvObject;
import languageacquisition.ontology.HasState;
import languageacquisition.ontology.LanguageOntology;
import languageacquisition.ontology.Vocabulary;

public class QueryObservationInitiator extends AchieveREInitiator {

	private static final long serialVersionUID = 966602133878954118L;
	protected AID observerAID;

	public QueryObservationInitiator(Agent myAgent, AID observerAID) {
		super(myAgent, new ACLMessage(ACLMessage.QUERY_REF));
		this.observerAID = observerAID;
		
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Vector prepareRequests(ACLMessage query) {
		Ontology ontology = LanguageOntology.getInstance();
		
		query.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
		query.setOntology(ontology.getName());
		query.setProtocol(FIPANames.InteractionProtocol.FIPA_QUERY);
		query.addReceiver(observerAID);
		
		try {
			// creating abstract object by given AID
			EnvObject envObject = new EnvObject(observerAID);
			AbsConcept absEnvObject = (AbsConcept) ontology.fromObject(envObject);

			AbsVariable absVar = new AbsVariable("x", Vocabulary.STATE);

			AbsPredicate absHasState = new AbsPredicate(Vocabulary.HASSTATE);
			absHasState.set(Vocabulary.HASSTATE_OBJECT, absEnvObject);
			absHasState.set(Vocabulary.HASSTATE_STATE, absVar);
			absHasState.set(Vocabulary.HASSTATE_TIME, 0);

			AbsIRE absIota = new AbsIRE(SLVocabulary.IOTA);
			absIota.setVariable(absVar);
			absIota.setProposition(absHasState);

			myAgent.getContentManager().fillContent(query, absIota);
		} catch (OntologyException oe) {
			oe.printStackTrace();
		} catch (CodecException ce) {
			ce.printStackTrace();
		}

		return super.prepareRequests(query);
	}
	
	final protected void handleInform(ACLMessage inform) {
		try {
			ContentElement content = myAgent.getContentManager().extractContent(inform);
			if (content instanceof HasState) {
				HasState hasState = (HasState) content;
				handleObservation(hasState);
			}
			else {
				System.err.println("HasState expected. Message not understood.");
			}
		} catch (UngroundedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CodecException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (OntologyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	protected void handleObservation(HasState hasState) {
		
	}
	
	protected void handleRefuse(ACLMessage refuse) {
		System.out.println("Agent " + refuse.getSender().getName()
				+ " refused to perform the requested action");
	}

	protected void handleFailure(ACLMessage failure) {
		if (failure.getSender().equals(myAgent.getAMS())) {
			// FAILURE notification from the JADE runtime: the receiver
			// does not exist
			System.out.println("Responder does not exist");
		} else {
			System.out.println("Agent " + failure.getSender().getName()
					+ " failed to perform the requested action");
		}
	}
}
